﻿using System;
using System.Collections;
using UnityEngine;

/// <summary>
///     to simulate the Velocity ( m / second )
///     Hook: SetPositionAction, default is set transform position
/// </summary>
class VelocitySimulate : MonoBehaviour
{
    public delegate void SetPositionDelegate(Vector3 resultPosition);

    public enum VelocityType
    {
        once, useCurve, sinIn, sinOut, sinInOut, // ... TODO add more ease type
    }

    // ***

    public SetPositionDelegate SetPositionAction;

    Vector3 _velocity = Vector3.zero;

    public Vector3 LastVelocity { get; private set; }

    void Awake()
    {
        SetPositionAction = defaultSetPositionAction;
    }

    void Update()
    {
        // move a second, the  * Time.deltaTime
        SetPositionAction(transform.position + (_velocity * Time.deltaTime));
        LastVelocity = _velocity;
        _velocity = Vector3.zero; // refresh and wait next v
    }

    void defaultSetPositionAction(Vector3 resultPosition)
    {
        transform.position += _velocity;
    }

    /// <summary>
    ///     a v that tend to set this object to the position, in a second
    ///     translate this to a velocity.
    /// </summary>
    public void addVelocityFromPosition(Vector3 p)
    {
        addVelocity((p - transform.position) * 50); // only add this velocity one tick
    }

    /// <summary>
    ///     add the v as a velocity in this tick
    /// </summary>
    /// <param name="v"></param>
    public void addVelocity(Vector3 v)
    {
        _velocity += v;
    }

    /// <summary>
    ///     default type is once
    /// </summary>
    public void addVelocity(Vector3 v, VelocityType vType)
    {
        // default type is once
        throw new NotImplementedException();
    }

    /// <summary>
    ///     if the last lastTime is smaller than 0, use default instead
    /// </summary>
    public void addVelocity(Vector3 v, float lastTime)
    {
        // if the lastTime == 0, the type is once
        if (lastTime <= 0)
        {
            addVelocity(v);
        }
        else
        {
            StartCoroutine(addVelocityForAWhile(v, lastTime));
        }
    }

    IEnumerator addVelocityForAWhile(Vector3 v, float lastTime)
    {
        var t = 0f;
        while (t < lastTime)
        {
            t += Time.deltaTime;
            addVelocity(v);
            yield return null;
        }
    }
}